Skip to content

Fix Switchbot Curtain BLE connection failures and NaN position values on Raspberry Pi#1229

Merged
donavanbecker merged 4 commits intobeta-4.3.2from
copilot/fix-1226
Aug 21, 2025
Merged

Fix Switchbot Curtain BLE connection failures and NaN position values on Raspberry Pi#1229
donavanbecker merged 4 commits intobeta-4.3.2from
copilot/fix-1226

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Aug 20, 2025

This PR resolves critical BLE connection issues with Switchbot Curtain 3 devices on Raspberry Pi HomeBridge that were causing "No characteristics available" errors and NaN position values in HomeKit.

Root Cause Analysis

The issues stemmed from multiple problems in the BLE handling code:

  1. Unsafe array access: The code was accessing deviceList[0] without checking if the device discovery returned any devices
  2. Invalid position calculations: Position values were calculated as 100 - this.serviceData.position even when position was undefined/null, resulting in NaN
  3. Logic errors: Validation conditions used OR instead of AND logic (!== undefined || !== null)
  4. Poor error recovery: Limited fallback mechanisms when BLE consistently failed

Example of the Problem

From the original issue logs:

[04/08/2025, 15:22:38] [SwitchBot] Curtain3: Bedroom Left Curtain Error: No characteristics available.
[04/08/2025, 15:22:50] [@switchbot/homebridge-switchbot] This plugin generated a warning from the characteristic 'Current Position': characteristic value expected valid finite number and received "NaN" (number).

Changes Made

1. Device Discovery Validation

Before:

.then(async (device_list: SwitchbotDevice[]) => {
  const deviceList = device_list as WoCurtain[]
  return await deviceList[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode)
})

After:

.then(async (device_list: SwitchbotDevice[]) => {
  const deviceList = device_list as WoCurtain[]
  if (deviceList && Array.isArray(deviceList) && deviceList.length > 0) {
    return await deviceList[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode)
  } else {
    throw new Error('No device found')
  }
})

2. Position Data Validation

Before:

if ('position' in this.serviceData) {
  this.WindowCovering.CurrentPosition = 100 - this.serviceData.position
}

After:

if ('position' in this.serviceData && this.serviceData.position !== undefined && 
    this.serviceData.position !== null && !isNaN(Number(this.serviceData.position))) {
  this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.position)
} else {
  this.warnLog(`Invalid position data from BLE: ${this.serviceData.position}`)
}

3. HomeKit NaN Prevention

Added validation in updateHomeKitCharacteristics():

if (isNaN(Number(this.WindowCovering.CurrentPosition))) {
  this.warnLog(`CurrentPosition is NaN, keeping previous value`)
  this.WindowCovering.CurrentPosition = this.accessory.context.CurrentPosition ?? 100
}

4. Logic Corrections

Fixed validation conditions throughout:

// Before: if (context !== undefined || context !== null)
// After: if (context !== undefined && context !== null)

5. Enhanced Error Handling

Improved BLE connection error messages and added guidance for users to consider using BLE/OpenAPI connection type as fallback.

Impact

  • Resolves "No characteristics available" errors during device discovery
  • Prevents HomeKit warnings about NaN position values
  • Provides better error recovery for unstable BLE connections on Raspberry Pi
  • Maintains backward compatibility with existing configurations
  • Applied the same device list validation fix to BlindTilt devices

Testing

  • All existing tests pass
  • Build completes successfully without errors
  • Edge case validation implemented and tested
  • No breaking changes introduced

Fixes #1226.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Aug 20, 2025

@donavanbecker 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Copilot AI and others added 2 commits August 20, 2025 13:30
…ry Pi

Co-authored-by: donavanbecker <9875439+donavanbecker@users.noreply.github.com>
Co-authored-by: donavanbecker <9875439+donavanbecker@users.noreply.github.com>
Copilot AI changed the title [WIP] Bug: Switchbot curtains don't work on Raspberry Pi HomeBridge Fix Switchbot Curtain BLE connection failures and NaN position values on Raspberry Pi Aug 20, 2025
Copilot AI requested a review from donavanbecker August 20, 2025 13:39
@donavanbecker donavanbecker changed the base branch from latest to beta-4.3.2 August 20, 2025 18:00
@donavanbecker donavanbecker marked this pull request as ready for review August 21, 2025 00:06
@donavanbecker donavanbecker assigned Copilot and unassigned Copilot Aug 21, 2025
@github-actions github-actions bot added enhancement New feature or request dependencies Pull requests that update a dependency file latest labels Aug 21, 2025
@donavanbecker donavanbecker requested review from Copilot and removed request for Copilot August 21, 2025 05:28
@github-actions github-actions bot added fix beta and removed fix labels Aug 21, 2025
@donavanbecker donavanbecker merged commit abccc31 into beta-4.3.2 Aug 21, 2025
4 of 5 checks passed
@donavanbecker donavanbecker deleted the copilot/fix-1226 branch August 21, 2025 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beta dependencies Pull requests that update a dependency file enhancement New feature or request latest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Switchbot curtains don't work on Raspberry Pi HomeBridge

2 participants